/**
 * @Author：ming
 * @Date：2023/10/2 12:33 AM
 * @Filename：Lc130
 */

/**
 * @author ming
 */
public class Lc130 {
    public void solve(char[][] board) {

        int len = board.length;
        int rLen = board[0].length;
        //边界O标记并改变
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < rLen; j++) {
                setZ(board,i,j);
            }
        }
        //非边界O置X
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < rLen; j++) {
                if(board[i][j]=='O'){
                    board[i][j]='X';
                }
            }
        }
        //边界O复原
        for (int i = 0; i < len; i++) {
            for (int j = 0; j < rLen; j++) {
                if(board[i][j]=='Z'){
                    board[i][j]='O';
                }
            }
        }

    }

    public void setZ(char[][] board,int r,int c){
        //本身为X或者已经设置过的直接退出
        if(board[r][c]=='X'||board[r][c]=='Z'){
            return;
        }
        int len = board.length;
        int rLen = board[0].length;

        //本身为边界0，置为Z
        if(r==0||r==len-1||c==0||c==rLen-1){
            if(board[r][c]=='O') {
                board[r][c] = 'Z';
            }
        }

        //四周某一个为边界O延伸，置为Z
        if(inFind(board,r,c-1)){
            if(board[r][c-1]=='Z'){
                board[r][c]='Z';
            }
        }
        if(inFind(board,r,c+1)){
            if(board[r][c+1]=='Z'){
                board[r][c]='Z';
            }
        }
        if(inFind(board,r-1,c)){
            if(board[r-1][c]=='Z'){
                board[r][c]='Z';
            }
        }
        if(inFind(board,r+1,c)){
            if(board[r+1][c]=='Z'){
                board[r][c]='Z';
            }
        }

        //边界O和其延伸，继续向四周延伸
        if(board[r][c]=='Z'){
            if(inFind(board,r-1,c)){
                setZ(board,r-1,c);
            }
            if(inFind(board,r+1,c)){
                setZ(board,r+1,c);
            }
            if(inFind(board,r,c-1)){
                setZ(board,r,c-1);
            }
            if(inFind(board,r,c+1)){
                setZ(board,r,c+1);
            }
        }

    }


    //坐标是否合法
    public boolean inFind(char[][] board,int r,int c){
        return r>=0&&r<board.length&&
                c>=0&&c<board[0].length;
    }
}
